import { Message } from 'element-ui';

import { randomUUID } from '../../../../mapUtils/RandomUtil';
import Layer from '../../constant/Layer';

/**
 * 区域组件
 */
class Region {
  constructor(_, qyfl) {
    this.tool = _;
    this.qyfl = qyfl;
    this.id = randomUUID();
    this.layeridPrefix = _.layeridPrefix + '_' + qyfl;
    this._layerclick = this.layerClick.bind(this);
    this.regionFeatures = [];
    this.selectedArea = null;
    this.areaUpdated = false;
    this.areaEditing = false;
    this.events = {
      onComplete: () => { }
    };
    this.init();
  }

  /**
   * 获取地图对象
   * @ignore
   */
  getMap() {
    return this.tool.getMap();
  }

  /**
   * 获取工具箱
   * @param {String} toolname 工具箱名称
   * @ignore
   */
  getTool(toolname) {
    return this.tool.getTool(toolname);
  }

  /**
   * 设置事件方法
   * @param {*} _events 事件方法
   */
  setEvents(_events) {
    for (let key in _events) {
      this.events[key] = _events[key];
    }
  }

  /**
   * 加载区域
   * @param {features} features 区域图形数据
   */
  render(features) {
    this.regionFeatures = features;
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection(features));
    setTimeout(() => {
      if (this.tool.changeType === 'add') {
        this.draw();
      } else if (this.tool.changeType === 'edit') {
        this.edit();
      }
    }, 100);
  }

  /**
   * 绘制区域
   * @param {*} events 绘制事件
   */
  draw(events) {
    if (events) {
      this.setEvents(events);
    }
    this.getMap().off('click', this._layerclick);
    this.getTool('EditTool').changeMode('snap_polygon');
    this.getTool('EditTool').enableSnap();
    this.getTool('EditTool').setSnapFeatures(this.tool.totalFeatures);
    this.getTool('EditTool').events.onSelectionchange = (e) => {
      if (e.features.length === 0) {
        let data = this.getTool('EditTool').getAll();
        this.events.onComplete(data.features[0]);
        this.getTool('EditTool').reset();
      }
    };
  }

  /**
   * 编辑区域
   * @param {*} events 编辑事件
   */
  edit(events) {
    if (events) {
      this.setEvents(events);
    }
    this.areaEditing = true;
    this.getMap().on('click', this._layerclick);
  }

  /**
   * 分割区域
   */
  split() {
    return new Promise((resolve, reject) => {
      if (this.selectedArea) {
        let originArea = this.selectedArea;
        this.reset();
        let polygon = turf.polygon(originArea.geometry.coordinates);
        setTimeout(() => {
          this.getMap().off('click', this._layerclick);
          this.getTool('EditTool').startSplit(polygon).then((result) => {
            this.getMap().on('click', this._layerclick);
            resolve({
              origin: originArea.properties,
              result: result
            });
          });
        }, 100);
      } else {
        Message.warning({ message: '请选择要分割的区域' });
        reject();
      }
    });
  }

  /**
   * 刷新图层
   */
  refresh() {
    this.regionFeatures.forEach((feature) => {
      let style = this.tool.getStyleByQyfl(feature.properties.qyfl);
      feature.properties = Object.assign(feature.properties, style);
    });
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection(this.regionFeatures));
  }

  /**
   * 清空图层
   */
  clear() {
    this.totalFeatures = [];
    this.regionFeatures = [];
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([]));
  }

  /**
   * 重置编辑工具
   */
  reset() {
    this.areaUpdated = false;
    this.areaEditing = false;
    this.selectedArea = null;
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection(this.regionFeatures));
    this.getTool('EditTool').reset();
    this.getMap().off('click', this._layerclick);
  }

  /**
   * 图层点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  layerClick(e) {
    let features = this.getMap().queryRenderedFeatures(e.point, { layers: [this._polygonLayerId] });
    if (features[0]) {
      this.getMap().off('click', this._layerclick);
      let feature = features[0];
      this.selectedArea = feature;
      // 将正在编辑的区域从原图层中隐藏
      let tempFeatures = [];
      this.regionFeatures.forEach((region) => {
        if (region.properties.oid !== feature.properties.oid) {
          tempFeatures.push(region);
        }
      });
      this.getMap().getSource(this._sourceId).setData(turf.featureCollection(tempFeatures));
      // 加载编辑区域
      let geometry = feature.properties.geometry ? JSON.parse(feature.properties.geometry) : feature.geometry;
      let id = feature.properties.id = feature.properties.oid;
      this.getTool('EditTool').editFeatures([turf.feature(geometry, feature.properties, { id: id })]);
      this.getTool('EditTool').changeMode('direct_select', { featureId: id });
      this.getTool('EditTool').enableSnap();
      this.getTool('EditTool').setSnapFeatures(this.tool.totalFeatures);
      this.getTool('EditTool').events.onUpdate = () => {
        this.areaUpdated = true;
      };
      this.getTool('EditTool').events.onSelectionchange = (se) => {
        if (se.features.length === 0) {
          if (this.areaUpdated) {
            let data = this.getTool('EditTool').getAll();
            this.events.onComplete(data.features[0]);
          } else {
            this.getMap().getSource(this._sourceId).setData(turf.featureCollection(this.regionFeatures));
          }
          this.areaUpdated = false;
          this.selectedArea = null;
          this.getTool('EditTool').reset();
          if (this.areaEditing) {
            this.getMap().on('click', this._layerclick);
          }
        }
      };
    }
  }

  /**
   * 初始化
   * @ignore
   */
  init() {
    this.initId();
    this.initLayer();
  }

  /**
   * 初始化图层Id
   * @ignore
   */
  initId() {
    // 数据源
    this._sourceId = this.layeridPrefix + '_source_' + this.id;
    // 图层
    this._polygonLayerId = this.layeridPrefix + '_Polygon' + this.id;
    this._strokeLayerId = this.layeridPrefix + '_PolygonStroke' + this.id;
    this._labelLayerId = this.layeridPrefix + '_PolygonLabel' + this.id;
  }

  /**
   * 初始化图层
   * @ignore
   */
  initLayer() {
    // 初始化数据源
    if(!this.tool.getMap().getSource(this._sourceId)) {
      this.tool.getMap().addSource(this._sourceId, {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      });
    }
    // 初始化图层
    if(!this.tool.getMap().getLayer(this._polygonLayerId)) {
      this.tool.getMap().addLayer({
        id: this._polygonLayerId,
        type: 'fill',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Polygon']],
        paint: {
          'fill-color': ['get', 'color'],
          'fill-opacity': ['get', 'opacity']
        }
      });
    }
    if(!this.tool.getMap().getLayer(this._strokeLayerId)) {
      this.tool.getMap().addLayer({
        id: this._strokeLayerId,
        type: 'line',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Polygon']],
        paint: {
          'line-color': ['get', 'line-color'],
          'line-opacity': ['get', 'line-opacity'],
          'line-width': ['get', 'line-width']
        }
      });
    }
    if(!this.tool.getMap().getLayer(this._labelLayerId)) {
      this.tool.getMap().addLayer({
        id: this._labelLayerId,
        type: 'symbol',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Point']],
        layout: {
          'icon-anchor': 'center',
          'text-field': '{' + Layer.GlobalMarkLabelField + '}',
          'text-size': 12,
          'text-font': ['Microsoft YaHei Regular'],
          'text-offset': [0, 0],
          'text-max-width': 8,
          'text-allow-overlap': false,
          'text-ignore-placement': false,
          'text-anchor': 'top'
        },
        paint: {
          'text-color': '#555252',
          'text-halo-color': '#FFFFFF',
          'text-halo-width': 1.33333
        }
      });
    }
  }
}

export default Region;
